package com.honor.games.wg.services;

import java.awt.Color;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.honor.games.wg.config.ApplicationConfiguration;
import com.honor.games.wg.entities.WGPlayerType;
import com.honor.games.wg.entities.WGTile;
import com.honor.games.wg.entities.WGUnit;
import com.honor.games.wg.entities.WGUnitType;
import com.honor.games.wg.gui.DebugFrame;

@Service
public class WGDebugConsoleService {

	private static Logger logger = LoggerFactory.getLogger(WGDebugConsoleService.class);

	@Autowired
	private ApplicationConfiguration config;

	@Autowired
	private DebugFrame debugFrame;

	@Autowired
	private WGWorldServices worldServices;

	public void handleCreateCommand(String eventCommand) {

		logger.trace("Handle create command - START");

		String[] parameters = eventCommand.split(" ");
		WGUnitType unitType = WGUnitType.ELVE;
		WGPlayerType playerType = WGPlayerType.PLAYER1;
		int locationX = 0;
		int locationY = 0;

		if (parameters[1].equals("unit")) {
			String errorMessage = "";
			boolean errorExists = false;

			if (parameters.length != 6) {
				errorExists = true;
				errorMessage = "Incorrect amount of parameters. Usage : create %unit% %unitType% %player% %x% %y%\n";
			} else {
				unitType = WGUnitType.getUnitTypeForString(parameters[2]);
				playerType = WGPlayerType.getPlayerType(parameters[3]);

				try {
					locationX = Integer.valueOf(parameters[4]);
					locationY = Integer.valueOf(parameters[5]);

					if ((locationX >= config.getBoardTilesWidthNumber() || locationX < 0)
							|| (locationY >= config.getBoardTilesHeightNumber() || locationY < 0)) {
						errorExists = true;
						errorMessage = "Errors : x and y must be between the board bounds. x, y >= 0, x <= "
								+ (config.getBoardTilesWidthNumber() - 1) + " and y <= " + (config.getBoardTilesHeightNumber() - 1) + ".\n";
					} else {
						if (worldServices.unitExists(locationX, locationY)) {
							errorExists = true;
							errorMessage = "Errors : unit already exists at " + locationX + ", " + locationY
									+ ". Can't create a new one.\n";
						}
					}

				} catch (NumberFormatException e) {
					errorExists = true;
					errorMessage = "Errors : x and y must be integers (current : x->" + parameters[4] + ",y->" + parameters[5]
							+ "). Usage : create %unit% %unitType% %player% %x% %y%\n";
				}
			}

			if (errorExists) {
				logger.trace("Error : {}", errorMessage);
				debugFrame.appendTextToConsole(Color.RED, errorMessage);
			} else {
				worldServices.createUnit(unitType, playerType, locationX, locationY);
			}
		}

		logger.trace("Handle create command - STOP");
	}

	public void handlePrintObjectCommand(String eventCommand) {
		logger.trace("Handle print tile command - START");

		String[] parameters = eventCommand.split(" ");
		if (parameters[1].equals("tile")) {
			String errorMessage = "";
			boolean errorExists = false;
			int locationX = 0;
			int locationY = 0;

			if (parameters.length != 4) {
				errorExists = true;
				errorMessage = "Incorrect amount of parameters. Usage : print %tile% %x% %y%\n";
			} else {

				try {
					locationX = Integer.valueOf(parameters[2]);
					locationY = Integer.valueOf(parameters[3]);

					if ((locationX >= config.getBoardTilesWidthNumber() || locationX < 0)
							|| (locationY >= config.getBoardTilesHeightNumber() || locationY < 0)) {
						errorExists = true;
						errorMessage = "Errors : x and y must be between the board bounds. x, y >= 0, x <= "
								+ (config.getBoardTilesWidthNumber() - 1) + " and y <= " + (config.getBoardTilesHeightNumber() - 1) + ".\n";
					}

				} catch (NumberFormatException e) {
					errorExists = true;
					errorMessage = "Errors : x and y must be integers (current : x->" + parameters[2] + ",y->" + parameters[3]
							+ "). Usage : create %unit% %unitType% %player% %x% %y%\n";
				}
			}

			if (errorExists) {
				logger.trace("Error : {}", errorMessage);
				debugFrame.appendTextToConsole(Color.RED, errorMessage);
			} else {
				WGTile tile = worldServices.getTile(locationX, locationY);
				debugFrame.appendTextToConsole(Color.BLUE, "Tile(" + locationX + ", " + locationY + "); type = " + tile.getTileType()
						+ "; empty = " + tile.isEmpty() + "; unit : " + (tile.isEmpty() ? null : tile.getUnit().getUnitType()) + "\n");
			}
		} else if (parameters[1].startsWith("unit")) {
			String errorMessage = "";
			boolean errorExists = false;
			int locationX = 0;
			int locationY = 0;

			if (parameters.length != 4) {
				errorExists = true;
				errorMessage = "Incorrect amount of parameters. Usage : print %unit% %x% %y%\n";
			} else {

				try {
					locationX = Integer.valueOf(parameters[2]);
					locationY = Integer.valueOf(parameters[3]);

					if ((locationX >= config.getBoardTilesWidthNumber() || locationX < 0)
							|| (locationY >= config.getBoardTilesHeightNumber() || locationY < 0)) {
						errorExists = true;
						errorMessage = "Errors : x and y must be between the board bounds. x, y >= 0, x <= "
								+ (config.getBoardTilesWidthNumber() - 1) + " and y <= " + (config.getBoardTilesHeightNumber() - 1) + ".\n";
					}

				} catch (NumberFormatException e) {
					errorExists = true;
					errorMessage = "Errors : x and y must be integers (current : x->" + parameters[2] + ",y->" + parameters[3]
							+ "). Usage : create %unit% %unitType% %player% %x% %y%\n";
				}
			}
			WGTile tile = worldServices.getTile(locationX, locationY);
			WGUnit unit = tile.getUnit();
			if (tile.isEmpty()) {
				errorExists = true;
				errorMessage = "Error : the tile at " + locationX + ", " + locationY + " must contain a unit";
			}

			if (errorExists) {
				logger.trace("Error : {}", errorMessage);
				debugFrame.appendTextToConsole(Color.RED, errorMessage);
			} else {
				debugFrame.appendTextToConsole(Color.BLUE, "Unit id: " + unit.getId() + "; type: " + unit.getUnitType() + "; player: "
						+ unit.getPlayer().getPlayerType() + "\n");
			}
		}

		logger.trace("Handle print tile command - STOP");
	}

	public void handleUnknownCommand(String eventCommand) {
		logger.trace("Handle Unknown command - START");
		debugFrame.appendTextToConsole(Color.RED, "Unknwon command : " + eventCommand + "\n");
		logger.trace("Handle Unknown command - STOP");
	}
}
